#include "camera.h"

Camera::Camera(){}

Camera::Camera(double speed,double eyeX,double eyeY,double eyeZ , double lx , double ly , double lz){

    this->speed = speed;

    this->eyeX = eyeX;
    this->eyeY = eyeY;
    this->eyeZ = eyeZ;

    this->lx = lx;
    this->ly = ly;
    this->lz = lz;

    pxX = 1.0;
    pyX = 0.0;
    pzX = 0.0;

    pxY = 0.0;
    pyY = 1.0;
    pzY = 0.0;

    angleY = acos(-lz / sqrt(lx * lx + ly * ly + lz * lz));
    angleX = asin(ly / sqrt(lx * lx + ly * ly + lz * lz));
}

void Camera::pan(double dt , bool axis){
    //The pan is defined for the X and Y axis

    if(axis == X_AXIS){
        //Updating the panX vector by the cross product between the view vector and the normal (0,1,0). The terms reduced to zero are not being calculated.

        pxX = -(lz * 0.1);
        pzX = (lx * 0.1);

        //normalizing
        double squareRootLength = sqrt(pxX * pxX + pzX * pzX);
        pxX = pxX / squareRootLength;
        pzX = pzX / squareRootLength;

        eyeX += speed * dt * pxX;
        eyeZ += speed * dt * pzX;
    }
    else{
        //Updating the panY vector by the cross product between the view vector and the vector (1,0,0). The terms reduced to zero are not being calculated.
        //[a2b3 - a3b2, a3b1 - a1b3, a1b2 - a2b1]

        pyY = lz * 1.0;
        pzY = -(ly * 1.0);

        if(lz < 0){
            pyY = -pyY;
            pzY = -pzY;
        }

        //normalizing
        double squareRootLength = sqrt(pyY * pyY + pzY * pzY);
        pyY = pyY / squareRootLength;
        pzY = pzY / squareRootLength;

        eyeY += speed * dt * pyY;
        eyeZ += speed * dt * pzY;
    }
}

void Camera::zoom(double dt) {
    //Zoom the camera in the direction of the view vector

    eyeX += speed * dt * lx;
    eyeY += speed * dt * ly;
    eyeZ += speed * dt * lz;
}

void Camera::rotate(double dt , bool axis){
    //The rotation is defined only for X and Y axis

    if(axis == X_AXIS){
        angleX += speed * dt;
        double piSobreDois = 1.57079635;

        //We don't want the cam to rotate too much in this axis
        if(fabs(angleX) > piSobreDois){
            if(angleX > 0)
                angleX = piSobreDois;
            else
                angleX = -piSobreDois;
        }
        ly = sin(angleX);
    }
    else{
        angleY += speed * dt;
        lx = sin(angleY);
        lz = -cos(angleY);
    }
}

void Camera::pointTo(double x , double y , double z){
    //Points the camera to the object in (x,y,z) coordinates

    eyeX = x;
    eyeY = y;
    eyeZ = z + 100;

    lx = 0.0;
    ly = 0.0;
    lz = -1.0;

    pxX = 1.0;
    pyX = 0.0;
    pzX = 0.0;

    pxY = 0.0;
    pyY = 1.0;
    pzY = 0.0;

    angleY = 0.0;
    angleX = 0.0;

}
